import { SectionSchema, SectionToolbarItemSchema } from '../schema/schema';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { SectionProp } from '../property/property-config';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';
import { SectionContextMenuManager } from '../context-menu/context-menu.manager';
import { RowNode } from '@farris/ui-treetable';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { OperateUtils } from '../../../../utils/operate.utils';
import FdSectionToolBarComponent from './fd-section-toolbar';
import { BuilderHTMLElement, FarrisDesignBaseComponent } from '@farris/designer-element';
import { DgControl } from '../../../../utils/dg-control';
import { FormComponentType, DomService, SchemaService, DesignerEnvType } from '@farris/designer-services';
import { FieldManagerComponent } from '@farris/designer-devkit';
import { SectionDragDropManager } from '../drag-drop/dragAndDrapManager';
import { ComponentFactoryResolver, Injector } from '@angular/core';
import { BsModalService } from '@farris/ui-modal';
import { ContentContainerSchema } from '../../content-container/schema/schema';
import { cloneDeep } from 'lodash-es';

export default class FdSectionComponent extends FdContainerBaseComponent {
    // 标记当前展开状态
    expandStatus: boolean;

    // 当前选中的项
    activeTypeItem;

    // 查找ref=form的项
    private formParent = null;
    private multiViewContainerEl = null;
    toolBarComponent: FdSectionToolBarComponent;

    // 标识当前viewChangeKey
    get viewChangeKey(): string {
        if (this.component.multiViews && this.component.views) {
            return this.component.views.viewGroupIdentify;
        }
        return `viewChange-${this.key}`;
    }
    // 标识当前的点击按钮
    get collapseKey(): string {
        return `SectionCollapse-${this.key}`;
    }

    /** 判断当前section是否是模板中预置的层级，这种section不支持移动、不支持删除 */
    private isInFixedContextRules: boolean;

    private dragManager: SectionDragDropManager;

    /** 当前是否选中工具栏 */
    isToolbarSelected = false;

    constructor(component: any, options: any) {
        super(component, options);
        this.customToolbarConfigs = [];

        this.dragManager = new SectionDragDropManager(this);
        this.isInFixedContextRules = this.dragManager.checkIsInFixedContextRules();

    }
    /**
     * 从工具箱拖拽生成的不是Section，而是Container-Section两层结构
     */
    static getMetadataInControlBox(targetComponentInstance: FarrisDesignBaseComponent) {
        const radomNum = Math.random().toString().slice(2, 6);

        const sectionSchema = cloneDeep(SectionSchema);
        Object.assign(sectionSchema, {
            id: `section_${radomNum}`,
            appearance: {
                class: 'f-section-in-mainsubcard'
            },
            enableAccordion: false
        });

        const containerSchema = cloneDeep(ContentContainerSchema);
        Object.assign(containerSchema, {
            id: `container_${radomNum}`,
            appearance: {
                class: 'f-struct-wrapper'
            },
            contents: [sectionSchema]
        });


        // 判断拖拽的目标容器
        const targetComponentSchema = targetComponentInstance.component;
        const targetComponentClassName = (targetComponentSchema && targetComponentSchema.appearance && targetComponentSchema.appearance.class) || '';
        switch (targetComponentSchema && targetComponentSchema.type) {
            case DgControl.ContentContainer.type: {
                // 卡片模板：判断子表是否需要设置为填充
                if (targetComponentSchema.isLikeCardContainer && targetComponentClassName.includes('f-struct-like-card-child-fill')) {
                    containerSchema.appearance.class += ' f-struct-wrapper-child';
                    sectionSchema.fill = true;
                }
                break;
            }
            case DgControl.Splitter.type: {
                // 左列右卡的模板：修改容器样式
                sectionSchema.appearance.class = 'f-section-in-main';

                // 左列右卡的模板：判断子表是否需要设置为填充
                const targetSplitterPane = targetComponentInstance.element.querySelector('.f-component-splitter-pane.f-page-child-fill.drag-over');
                if (targetSplitterPane) {
                    containerSchema.appearance.class += ' f-struct-wrapper-child';
                    sectionSchema.fill = true;
                }
                break;
            }

        }
        return containerSchema;
    }

    getDefaultSchema(): any {
        return SectionSchema;
    }

    getTemplateName(): string {
        return 'Section';
    }
    // css中 :host 部分
    getStyles(): string {
        return 'display: inherit;';
    }
    /**
     * 为适配多视图的切换，在Component中增加viewChagne属性
     */
    getComponentAttributes() {
        if (this.component.multiViews && this.component.views) {
            return {
                viewchange: this.component.views.viewGroupIdentify
            };
        }

    }
    // 初始化
    init(): void {
        this.expandStatus = this.component.expanded;
        super.init();
    }

    /**
     *  viewChange赋值
     */
    private getActiveTypeItem() {
        if (this.component.multiViews && this.component.views) {
            this.activeTypeItem = OperateUtils.viewChangeInitActiveItem(this.component.views.currentTypeInDesignerView || this.component.views.defaultType, this.activeTypeItem, this.component.views.toolbarData);
        }
    }
    // 渲染模板
    render(children): any {
        this.isInFixedContextRules = this.dragManager.checkIsInFixedContextRules();

        this.initToolbar();
        this.getActiveTypeItem();

        return super.render(children || this.renderTemplate('Section', {
            // 展开收起状态
            expandStatus: this.expandStatus,
            toolBarComponent: this.toolBarComponent,
            viewChangeKey: this.viewChangeKey,
            getViewChangeStr: () => this.getViewChangeStr(),
            collapseKey: this.collapseKey,
            children: this.renderComponents(),
            nestedKey: this.nestedKey
        }));
    }

    attach(element: any): any {
        // key 如果有多个用 multi，单个用single
        this.loadRefs(element, {
            [this.collapseKey]: 'single',
            [this.viewChangeKey]: 'single'
        });
        // 必写
        const superAttach: any = super.attach(element);

        // 注册収折按钮
        const collapseEl = this.refs[this.collapseKey];
        if (collapseEl) {
            this.addEventListener(collapseEl, 'click', (event) => {
                event.stopPropagation();
                this.expandStatus = !this.expandStatus;
                this.redraw();

                // 收折后涉及到了界面高度的变化，所以需要重新计算页面上控件操作图标的位置
                this.setPositionOfSelectedComponentBtnGroup();
            });
        }
        // 多视图
        if (this.component.multiViews && this.component.views) {
            // 绑定
            if (this.component.views.viewType === 'tile') {
                OperateUtils.bindTileEventForViewChange((obj, type, func) => { this.addEventListener(obj, type, func) }, this.component.views.toolbarData, this.activeTypeItem, this.refs[this.viewChangeKey], () => {
                    this.findMultiViewContainerEl();
                    return { multiViewContainerEl: this.multiViewContainerEl };
                }, (returnActiveItem) => {
                    this.activeTypeItem = returnActiveItem;
                    // 当前结构上保存
                    this.component.views.currentTypeInDesignerView = this.activeTypeItem['type'];
                    // 通过DOM操作更新viewchange
                    OperateUtils.updateTileByActiveType('tile', this.activeTypeItem, this.refs[this.viewChangeKey]);
                });

            } else if (this.component.views.viewType === 'dropdown') {
                OperateUtils.bindDropdownEventForViewChange((obj, type, func) => { this.addEventListener(obj, type, func) }, this.component.views.toolbarData, this.activeTypeItem, this.refs[this.viewChangeKey], () => {
                    this.findMultiViewContainerEl();
                    return { multiViewContainerEl: this.multiViewContainerEl };
                }, (returnActiveItem) => {
                    this.activeTypeItem = returnActiveItem;
                    // 当前结构上保存
                    this.component.views.currentTypeInDesignerView = this.activeTypeItem['type'];
                    // 通过DOM操作更新viewchange
                    OperateUtils.updateTileByActiveType('dropdown', this.activeTypeItem, this.refs[this.viewChangeKey]);
                });
            }
        }

        // 工具栏按钮绑定事件
        const toolBarEle = element.querySelector('.farris-component-SectionToolbar');
        if (toolBarEle && this.toolBarComponent) {
            this.toolBarComponent.attach(toolBarEle);
        }
        // 必写
        return superAttach;
    }

    /**
     * 组装属性面板配置数据
     * @returns ElementPropertyConfig[] 
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options.designerHost;

        // if (this.envType === DesignerEnvType.noCode) {
        //     const prop: NoCodeSectionProp = new NoCodeSectionProp(serviceHost, this.viewModelId, this.componentId);
        //     const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
        //     return propertyConfig;
        // } else {
        const prop: SectionProp = new SectionProp(serviceHost, this.viewModelId, this.componentId);
        const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
        return propertyConfig;
        // }
    }

    /**
     * 属性变更后事件
     * @param changeObject 变更集
     * @param propertyIDs 需要额外监听的属性ID列表
     */
    onPropertyChanged(changeObject: FormPropertyChangeObject, propertyIDs: string[]): void {
        // 调整工具栏位置后需要修改工具栏的样式属性
        if (changeObject.propertyID === 'position' && this.component.toolbar && this.toolBarComponent) {
            this.toolBarComponent.justifyContentEnd = changeObject.propertyValue === 'inHead';
        }

        // 若不显示头部区域，需要把展开属性设置为true，否则整个section都显示不出来了
        if (changeObject.propertyID === 'showHeader' && !changeObject.propertyValue) {
            this.expandStatus = true;
        }

        // 除收折模式和被滚动跟随的节点 属性外，都需要检测变更
        const notApplyPropertyIDs = ['visible', 'accordionMode', 'isScrollSpyItem'];

        if (!notApplyPropertyIDs.includes(changeObject.propertyID)) {
            this.triggerRedraw();
        }

    }
    /**
     * 组装右键菜单
     * @param rowNode 组件在控件树上对应的行数据
     */
    resolveContextMenuConfig(rowNode: RowNode) {
        const menuManager = new SectionContextMenuManager(this, rowNode);
        return menuManager.setContextMenuConfig();
    }
    /**
     * 查找multiViewContainerEl
     */
    private findMultiViewContainerEl() {
        if (this.multiViewContainerEl) {
            return;
        }
        if (!this.formParent) {
            this.formParent = OperateUtils.getFormParent(this.element);
        }
        if (this.formParent && !this.multiViewContainerEl) {
            // 查找同组的元素
            this.multiViewContainerEl = this.formParent.querySelector('.farris-component-MultiViewContainer[viewchange=' + this.component.views.viewGroupIdentify + ']');
        }
    }
    /**
     * 获取view chagne的字符串
     */
    getViewChangeStr() {
        if (!this.component.multiViews) {
            return '';
        }
        return OperateUtils.getViewChangeStr(this.component.views.toolbarData, this.component.views.viewType, this.activeTypeItem);
    }

    /**
     * 判断在可视化区域中是否隐藏容器间距和线条
     */
    hideNestedPaddingInDesginerView() {

        if (this.isInFixedContextRules) {
            return true;
        }
        return false;

    }

    checkCanMoveComponent(): boolean {
        return !this.isInFixedContextRules;
    }

    checkCanDeleteComponent(): boolean {
        return !this.isInFixedContextRules;
    }

    canAccepts(sourceElement: BuilderHTMLElement, targetElement: BuilderHTMLElement): boolean {
        const result = super.canAccepts(sourceElement, targetElement);
        if (!result) {
            return false;
        }
        return this.dragManager.canAccepts();

    }
    /**
     * 初始化工具栏
     */
    private initToolbar() {
        const toolbar = this.component.toolbar;
        const options = Object.assign({}, this.options, { parent: this });
        this.customToolbarConfigs.length = 0;

        this.addFieldManagerIcon();

        // 工具栏存在
        if (toolbar && toolbar.contents.length) {
            this.toolBarComponent = new FdSectionToolBarComponent(this.component.toolbar, options);
            this.toolBarComponent.init();
            this.toolBarComponent.justifyContentEnd = toolbar.position === 'inHead';
            return;
        }

        // 工具栏不存在。若显示头部区域并且表单有状态机且section的子级是DataGrid/Table/MultiViewContainer，且section没有配置过带按钮的头部扩展区域模板，section才支持启用按钮
        const domService = this.options.designerHost.getService('DomService') as DomService;
        const stateMachines = domService.module.stateMachines;
        if (!stateMachines || stateMachines.length === 0 || !this.component.showHeader) {
            return;
        }

        if (this.component.extendedHeaderAreaTemplate && this.component.extendedHeaderAreaTemplate.includes('<button')) {
            return;
        }
        const childContents = this.component.contents || [];
        const result = domService.selectNode(this.component, item => {
            if (item.type === DgControl.Table.type || item.type === DgControl.MultiViewContainer.type) {
                return true;
            }
            if (item.type === DgControl.ComponentRef.type) {
                const childCmp = domService.getComponentById(childContents[0].component);
                if (childCmp && childCmp.componentType === FormComponentType.dataGrid) {
                    return true;
                }
            }
            return false;
        });
        if (result) {
            this.customToolbarConfigs.push({
                id: 'appendToolbar',
                title: '新增工具栏',
                icon: 'f-icon f-icon-plus-circle text-white',
                click: (e) => {
                    e.stopPropagation();
                    this.toolBarComponent = new FdSectionToolBarComponent(this.component.toolbar, options);
                    this.toolBarComponent.appendItem(SectionToolbarItemSchema);
                    this.addStateMachineToViewModel();
                    this.toolBarComponent.parent.redraw();
                }
            }
            );

        }

    }
    /**
     * 新增工具栏后，需要将状态机信息增加到Section所属的视图模型中，不然运行时状态机不起作用
     */
    private addStateMachineToViewModel() {
        const domService = this.options.designerHost.getService('DomService');
        const viewModel = domService.getViewModelById(this.viewModelId);
        if (!viewModel.stateMachine) {
            viewModel.stateMachine = domService.module.stateMachines[0].id;

        }
    }
    /**
     * Section下若存放form控件，则增加一个字段维护的图标
     */
    private addFieldManagerIcon() {
        const childContents = this.component.contents || [];
        if (childContents.length !== 1) {
            return;
        }
        // 定位Form控件
        const formComponent = childContents[0] || {};
        if (formComponent.type !== DgControl.Form.type) {
            return;
        }
        // Form内不能包含Table
        const tableChild = formComponent.contents && formComponent.contents.length && formComponent.contents.find(c => c.type === DgControl.Table.type);
        if (tableChild) {
            return;
        }
        this.customToolbarConfigs.push(
            {
                id: 'fieldManager',
                title: '字段维护',
                icon: 'f-icon f-icon-home-setup',
                click: (e) => {
                    e.stopPropagation();
                    this.showFieldManager();
                }
            }
        );
    }

    /**
     * 弹出字段维护窗口
     */
    private showFieldManager() {
        // 动态创建相关的服务需要从designerHost中获取
        const serviceHost = this.options.designerHost;
        const resolver = serviceHost.getService('ComponentFactoryResolver') as ComponentFactoryResolver;
        const injector = serviceHost.getService('Injector') as Injector;
        const modalService = serviceHost.getService('ModalService') as BsModalService;
        const schemaService = serviceHost.getService('SchemaService') as SchemaService;

        const compFactory = resolver.resolveComponentFactory(FieldManagerComponent);
        const compRef = compFactory.create(injector);
        const modalConfig = {
            title: '维护控件',
            width: 950,
            height: 600,
            showButtons: true,
            buttons: compRef.instance.modalFooter
        };
        compRef.instance.viewModelId = this.viewModelId;
        compRef.instance.formId = this.component.id;
        const modalPanel = modalService.show(compRef, modalConfig);
        compRef.instance.closeModal.subscribe(() => {
            modalPanel.close();
        });

        compRef.instance.confirmModal.subscribe((data) => {
            const { addedFields, deletedFieldIds } = data;
            if (deletedFieldIds && deletedFieldIds.length) {
                schemaService.removeSchemaField(deletedFieldIds);
            }
            modalPanel.close();
        });

    }

}
